use anyhow::{anyhow, Result};
use std::{thread, sync::mpsc};
use std::fmt::Debug;
use std::ops::{Add, AddAssign, Mul};
use std::process::Output;
use std::sync::mpsc::channel;
use std::time::{Duration, Instant};
use rand::Rng;
use concurrency::{fmt, Matrix, matrix_multiply, matrix_multiply_concurrent};


fn main() -> Result<()> {
    let m1 = Matrix {
        data: vec![1, 2, 3, 4,
                   5, 6, 7, 8,
                   9, 10, 11, 12,
                   13, 14, 15, 16,
        ],
        row: 4,
        col: 4,
    };

    // fmt(&m1);

    let m2 = Matrix {
        data: vec![11, 12, 13, 14,
                   15, 16, 17, 18,
                   19, 20, 21, 22,
                   23, 24, 25, 26],
        row: 4,
        col: 4,
    };


    let start = Instant::now();


    let res = matrix_multiply(&m1, &m2)?;

    let duration = start.elapsed();

    println!("Time elapsed in matrix_multiply is: {:?}", duration);


    let start = Instant::now();


    let res = m1 * m2;

    let duration = start.elapsed();

    println!("Time elapsed in matrix_multiply_concurrent is: {:?}", duration);

    // fmt(&res);
    Ok(())
}
